﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using PloobsEngine;
using PloobsEngine.Cameras;
using PloobsEngine.Input;
using PloobsEngine.Light;
using PloobsEngine.Material;
using PloobsEngine.Modelo;
using PloobsEngine.Physics;
using PloobsEngine.Physics.Bepu;
using PloobsEngine.SceneControl;
using PloobsEngineDemo3;

namespace Etapa1.Screens
{
    /// <summary>
    /// Lod Screen
    /// </summary>
    public class LodScreen : SceneScreen
    {
        private BepuPhysicWorld physicWorld;
        private BrutalForceWorld mundo;
        private EngineStuff engine;        
        ICamera cam;

        public LodScreen(EngineStuff es)
        {
            this.engine = es;
            physicWorld = new BepuPhysicWorld();
            mundo = new BrutalForceWorld(physicWorld);                                    
        }
        
        public override void LoadContent(EngineStuff es)
        {            
            InputAdvanced inp = new InputAdvanced(engine);
            engine.AddComponent(inp);

            base.LoadContent(es);            

            #region Models

            ///Modelo do Marcus em alta resolucao
            ///primeiro da fila
            {
                SimpleModel sm = new SimpleModel("..\\Content\\Model\\Marcus_alta");
                sm.LoadModelo();
                GhostObject g = new GhostObject(new Vector3(100, 100, 100), Matrix.Identity, Vector3.One);                
                NormalDeferred shader = new NormalDeferred();
                shader.SpecularIntensity = 0.1f;
                shader.SpecularPower = 50;
                shader.Initialize();
                IMaterial mat = new Material(shader);
                IObject obj3 = new SimpleObject(mat, g, sm);
                mundo.AddObject(obj3);
            }

            ////segundo na fila q tem lod
            {
                ///Modelos do Marcus, alta e baixa resolucao
                SimpleModel sm1 = new SimpleModel("..\\Content\\Model\\Marcus_baja");
                SimpleModel sm2 = new SimpleModel("..\\Content\\Model\\Marcus_alta");
                sm1.LoadModelo();
                sm2.LoadModelo();

                ///Modelo Fisico
                GhostObject g = new GhostObject(new Vector3(100, 200, 100), Matrix.Identity, Vector3.One);
                ///Shader 
                CustomDeferred shader = new CustomDeferred(false,false,false,false);
                shader.SpecularIntensity = 0.01f;
                shader.SpecularPower = 50;
                shader.Initialize();
                IMaterial mat = new Material(shader);

                ///OBJETO COM LOD
                LodObject obj3 = new LodObject(mat, g, sm1);
                ///Adiciona os Lods e as correspondentes distancias q ele eh ativado
                ///sm2 estara ativo entre 0 e 200
                obj3.AddLod(sm2, null, 200);
                ///sm1 estara ativo entre 200 e MaxFloat(infinito)
                obj3.AddLod(sm1, null, float.MaxValue);
                mundo.AddObject(obj3);
            }

            ///Terceiro na fila
            ///Baixa resolucao
            {
                SimpleModel sm = new SimpleModel("..\\Content\\Model\\Marcus_baja");
                sm.LoadModelo();
                GhostObject g = new GhostObject(new Vector3(100, 300, 100), Matrix.Identity, Vector3.One);
                CustomDeferred shader = new CustomDeferred(false, false, false, false);
                shader.SpecularIntensity = 0.1f;
                shader.SpecularPower = 50;
                shader.Initialize();
                IMaterial mat = new Material(shader, MaterialType.DEFERRED);
                IObject obj3 = new SimpleObject(mat, g, sm);
                mundo.AddObject(obj3);
            }
            

            #endregion            

            cam = new CameraFirstPerson(true);            
            cam.FarPlane = 3000;

            LightThrowBepu lt = new LightThrowBepu(mundo, engine);         

            #region NormalLight
            DirectionalLight ld1 = new DirectionalLight(Vector3.Left, Color.White);
            DirectionalLight ld2 = new DirectionalLight(Vector3.Right, Color.White);
            DirectionalLight ld3 = new DirectionalLight(Vector3.Backward, Color.White);
            DirectionalLight ld4 = new DirectionalLight(Vector3.Forward, Color.White);
            DirectionalLight ld5 = new DirectionalLight(Vector3.Down, Color.White);
            float li = 0.4f;
            ld1.LightIntensity = li;
            ld2.LightIntensity = li;
            ld3.LightIntensity = li;
            ld4.LightIntensity = li;
            ld5.LightIntensity = li;
            mundo.AddLight(ld1);
            mundo.AddLight(ld2);
            mundo.AddLight(ld3);
            mundo.AddLight(ld4);
            mundo.AddLight(ld5);
            #endregion

            ////Criacao de uma Tecnica
            DeferredRenderTechnic dr = new DeferredRenderTechnic(engine);
            
            IRenderTechnic[] rt = new IRenderTechnic[] { dr };
            this.RenderTechnics = rt;
            mundo.AddCamera(cam);
            this.World = mundo;
        }
    }
}

